/*
 * Mail.cpp
 *
 *  Created on: 10/09/2010
 *      Author: julfc
 */

#include "Mail.h"

Mail::Mail() {

}

string Mail::getDate(string cadena) {
  string primerCharPorBuscar;
  primerCharPorBuscar.assign("Date: ");
  int inicio = obterPrimeraOcurrencia(cadena, 0, primerCharPorBuscar);
  if (inicio != -1) {
	  string segundoCharPorBuscar;
	  segundoCharPorBuscar.assign("\n");
	  int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
      inicio+=11;
      string subStr = cadena.substr(inicio, fin - 27);
      //Hago esto para solucionar un problema
      //el formato de las fechas varia parece.
      Parser parser;
      vector<string> splitDate = parser.Split(subStr, " ");
      if (splitDate.size() > 2) {
    	  if (splitDate[0].substr(0, 1) == "0") {
    		  //cout << "\n Se elimino un 0. \n";
    		  splitDate[0] = splitDate[0].substr(1, splitDate[0].size());
    	  }
    	  subStr = splitDate[0] + " " + splitDate[1] + " " + splitDate[2];

      }
      //cout << "\nLa fecha parseada es: " << subStr << "\n";
      return subStr;
  }
  return "";
}

string Mail::getSubject(string cadena) {
  string primerCharPorBuscar;
  primerCharPorBuscar.assign("Subject: ");
  int inicio = obterPrimeraOcurrencia(cadena, 0, primerCharPorBuscar);
  if (inicio != -1) {
	  string segundoCharPorBuscar;
	  segundoCharPorBuscar.assign("\n");
	  int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
      inicio+=9;
      string subStr = cadena.substr(inicio, fin - 10);
      return subStr;
  }
  return "";
}

string Mail::getFrom(string cadena) {
  string primerCharPorBuscar;
  primerCharPorBuscar.assign("From: ");
  int inicio = obterPrimeraOcurrencia(cadena, 0, primerCharPorBuscar);
  if (inicio != -1) {
	string segundoCharPorBuscar;
	segundoCharPorBuscar.assign("\n");
	int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
    inicio+=6;
    string subStr = cadena.substr(inicio, fin - 6);
    return limpiarDirMail(subStr);
  }
  return "";
}

vector<string> Mail::getTo(string cadena) {
  vector<string> resp;
  string primerCharPorBuscar;
  primerCharPorBuscar.assign("To: ");
  int inicio = obterPrimeraOcurrencia(cadena, 0, primerCharPorBuscar);
  if (inicio != -1) {
	string segundoCharPorBuscar;
	segundoCharPorBuscar.assign("\n");
	int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
    inicio+=4;
    string toSplit = cadena.substr(inicio, fin - 4);
    resp = splitMail(toSplit);
  }
  //for (unsigned int i = 0; i < resp.size(); i++)
//	  cout << resp[i] << endl;
  return resp;
}

vector<string> Mail::getCc(string cadena) {
  vector<string> resp;
  string primerCharPorBuscar;
  primerCharPorBuscar.assign("Cc: ");
  int inicio = obterPrimeraOcurrencia(cadena, 0, primerCharPorBuscar);
  if (inicio != -1) {
	string segundoCharPorBuscar;
	segundoCharPorBuscar.assign("\n");
	int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
    inicio+=4;
    string toSplit = cadena.substr(inicio, fin - 4);
    resp = splitMail(toSplit);
  }
  return resp;
}

//Devuelve el mail sin el header
string Mail::mailToString(char* cadena) {
  int found;
  int foundDate;
  int foundMessageId;
  string mailStr;
  string mailSinHeader;
  string charPorBuscar;
  charPorBuscar.assign("Date: ");
  mailStr.assign(cadena);
  foundDate = obterPrimeraOcurrencia(cadena, 0, charPorBuscar);

  string otroCharABuscar;
  otroCharABuscar.assign("Message-ID: ");
  foundMessageId = obterPrimeraOcurrencia(cadena, 0, otroCharABuscar);

  if (foundMessageId != -1 && foundDate != -1) {
	  if (foundDate < foundMessageId) {
		  found = foundDate;
	  } else {
		  found = foundMessageId;
	  }
  } else if (foundMessageId != -1) {
	  found = foundMessageId;
  } else if (foundDate != -1) {
	  found = foundDate;
  } else {
	  found = -1;
  }
  if (found != -1 || found < mailStr.size()) {
    mailSinHeader = mailStr.substr(found, mailStr.size() - found);
    return mailSinHeader;
  } else {
    return "";
  }
}

int Mail::obterPrimeraOcurrencia(string cadena, int desde, string cadenaABuscar) {
  size_t found;
  string subCadena;
  subCadena = cadena.substr(desde, cadena.size() - desde);
  found = subCadena.find(cadenaABuscar);
  if (found != string::npos) {
    //cout << "Se encontro la cadena en la pos " << int(found) << "\n\n";
    return int(found);
  }
  return -1;
}

string Mail::limpiarDirMail(string cadena) {
	Parser parser;
	string charPorBuscar;
	string segundoCharPorBuscar;
	string aDevolver;
	charPorBuscar.assign("<");
	int inicio = obterPrimeraOcurrencia(cadena, 0, charPorBuscar);
	if (inicio > -1) {
		segundoCharPorBuscar.assign(">");
		int fin = obterPrimeraOcurrencia(cadena, inicio, segundoCharPorBuscar);
		if (fin != -1) {
			inicio+=1;
			aDevolver = cadena.substr(inicio, fin - 1);
			vector<string> tieneEspacios = parser.Split(aDevolver, " ");
			if (tieneEspacios.size() > 1) {
				aDevolver = tieneEspacios[tieneEspacios.size()-1];
			}
			return aDevolver;
		}
	} else {
		char c1 = ' ';
		int desde = 0;
		int vacio = cadena.find(c1);
		if (vacio > -1)
			desde = 1;
		int hasta = cadena.size();
		char c2 = '\r';
		int garompa = cadena.find(c2);
		if (garompa > -1)
			hasta = garompa - 1;
		aDevolver = cadena.substr(desde, hasta - inicio);
		vector<string> tieneEspacios = parser.Split(aDevolver, " ");
		if (tieneEspacios.size() > 1) {
			aDevolver = tieneEspacios[tieneEspacios.size()-1];
		}
		return aDevolver;
	}
	//cout << "La direccion mal es: '" << aDevolver << "'\n\n";
	return "Bad Dir";
}

vector<string> Mail::splitMail(string &s) {
  vector<string> dirMails;
  char c = ',';
  size_t i = 0;
  size_t j = s.find(c);
  if (j == string::npos) {
    string mail0;
    mail0 = limpiarDirMail(s);
    if (mail0.compare("Bad Dir") != 0)
    	dirMails.push_back(mail0);
  } else {
    while (j != string::npos) {
      string mail;
      mail = s.substr(i, j-i);
      if (validarMail(mail)) {
        mail = limpiarDirMail(mail);
        if (mail.compare("Bad Dir") != 0)
        	dirMails.push_back(mail);
      }
      i = ++j;
      j = s.find(c, j);

      if (j == string::npos) {
        string mail2;
        mail2 = s.substr(i, s.length( ));
        if (validarMail(mail2)) {
          mail2 = limpiarDirMail(mail2);
          if (mail2.compare("Bad Dir") != 0)
        	  dirMails.push_back(mail2);
        }
      }
    }
  }
  return dirMails;
}

bool Mail::validarMail(string mail) {
  int arroba = mail.find('@');
  if (arroba > 0) {
    return true;
  } else {
    return false;
  }
}

string Mail::getBody(char* cadena) {
  return mailToString(cadena);
}


Mail::~Mail() {
	// TODO Auto-generated destructor stub
}
